package com.charlie.map;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 *
 * @author Vitaliy Mostipaka <imprtat@gmail.com>
 */
@Singleton
public class Map implements MapLocal {

    private SAXParserFactory saxFactory;

    @PostConstruct
    public void init() {
        saxFactory = SAXParserFactory.newInstance();
        saxFactory.setValidating(true);
    }

    @Override
    public int getDestination(String origin, String destination) {
        try {
            HashMap<String, String> args = new HashMap<String, String>();
            args.put("origin", origin);
            args.put("destination", destination);
            InputStream result = apiQuery(MapService.Directions, MapOutput.XML, args);
            SAXParser parser = saxFactory.newSAXParser();
            DirectionParserHandler handler = new DirectionParserHandler();
            parser.parse(result, handler);
            return handler.getDistance();
        } catch (Exception ex) {
            Logger.getLogger(Map.class.getName()).log(Level.SEVERE, null, ex);
        }
        return -1;
    }
    
    private String buildArgsString(HashMap<String, String> args) {
        StringBuilder res = new StringBuilder();
        for (String key : args.keySet()) {
            String value = args.get(key);
            try {
                String arg = key + "=" + URLEncoder.encode(value, "UTF-8");
                if (res.length() > 0) {
                    res.append("&");
                }
                res.append(arg);
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(Map.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return res.toString();
    }

    private InputStream apiQuery(MapService service, MapOutput out, HashMap<String, String> args) {
        args.put("sensor", "false");
        String url = "http://maps.googleapis.com/maps/api/" + service + "/" + out + "?" + buildArgsString(args);
        return httpQuery(url);
    }

    private InputStream httpQuery(String url) {
        try {
            URL target = new URL(url);
            URLConnection conn = target.openConnection();
            return conn.getInputStream();
        } catch (Exception ex) {
            return null;
        }
    }
}
